﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace DELVE_GAME.ViewStructure.MapEditor
{
    class MapEditorStage : Stage
    {
        Map myMap;
        MapDrawer mapComponent;
        List<MapEditorCell> selectedCells;
        View view;
        public Rectangle selectionBox;
        MouseState ms;
        MouseState prevMs;
        Texture2D selectionLine;
        bool isDragging;
        //Game game;

        public MapEditorStage( View view, Sprite tileSprite, Texture2D selectRect, Map map, MapDrawer mapComponent )
        {
            this.myMap = map;
            selectionLine = selectRect;
            this.view = view;
            selectionBox = new Rectangle(-1, -1, 0, 0);
            prevMs = Mouse.GetState();
            selectedCells = new List<MapEditorCell>();
            isDragging = false;
            this.mapComponent = mapComponent;
        }

        public void setMapComponent(MapDrawer mapComponent)
        {
            this.mapComponent = mapComponent;
        }

        public override void update()
        {
            /*foreach (ViewComponent vc in this.components)
            {
                vc.update();
            }*/

            mouseDrag();
        }

        public override void draw(SpriteBatch sb)
        {
            if (this.background != null)
            {
                sb.Begin();
                sb.Draw(background, new Rectangle(0, 0, 1024, 600), Color.White);
                sb.End();
            }
            foreach (ViewComponent vc in this.components)
            {
                vc.draw(sb);
            }

            mapComponent.draw(sb);

            sb.Begin();
            if (selectionBox.X != -1 && selectionBox.Y != -1)
            {
                //Draws the entire selection box area
                DrawHorizontalLine(selectionBox.Y, sb);
                DrawHorizontalLine(selectionBox.Y + selectionBox.Height, sb);
                DrawVerticalLine(selectionBox.X, sb);
                DrawVerticalLine(selectionBox.X + selectionBox.Width, sb);
            }
            sb.End();


        }

        #region Draw selection box helper methods
        private void DrawHorizontalLine(int posY, SpriteBatch sb)
        {
            //draws dotted line of 5 px moving right
            if (selectionBox.Width > 0)
            {
                for (int counter = 0; counter <= selectionBox.Width - 5; counter += 5)
                {
                    sb.Draw(selectionLine, new Rectangle(selectionBox.X + counter, posY, 5, 3), Color.White);
                }
            }
            //draws dotted line of 5 px moving left
            else if (selectionBox.Width < 0)
            {
                for (int counter = -5; counter >= selectionBox.Width; counter -= 5)
                {
                    if (selectionBox.Width - counter <= 0)
                    {
                        sb.Draw(selectionLine, new Rectangle(selectionBox.X + counter, posY, 5, 3), Color.White);
                    }
                }
            }
        }

        private void DrawVerticalLine(int posX, SpriteBatch sb)
        {
            if (selectionBox.Height > 0)
            {
                for (int counterY = 0; counterY <= selectionBox.Height; counterY += 5)
                {
                    //draws the dashed rectangle moving down, rotated 90 degrees
                    if (selectionBox.Height - counterY >= 0)
                    {
                        sb.Draw(selectionLine, new Rectangle(posX, selectionBox.Y + counterY, 5, 3),
                            new Rectangle(0, 0, selectionLine.Width, selectionLine.Height), Color.White, MathHelper.ToRadians(90), new Vector2(0, 0), SpriteEffects.None, 0);
                    }
                }
            }

            else if (selectionBox.Height < 0)
            {
                for (int counterY = 0; counterY >= selectionBox.Height; counterY -= 5)
                {
                    //draws rectangles moving up (bug with positioning)
                    if (selectionBox.Height - counterY <= 0)
                    {
                        sb.Draw(selectionLine, new Rectangle(posX, selectionBox.Y + counterY, 5, 3), Color.White);
                    }
                }
            }

        }
        #endregion

        #region Mouse Methods
        private void mouseDrag()
        {
            ms = Mouse.GetState();

            if (ms.LeftButton == ButtonState.Pressed && prevMs.LeftButton == ButtonState.Released)
            {
                selectionBox = new Rectangle(ms.X, ms.Y, 0, 0);
            }

            if (ms.LeftButton == ButtonState.Pressed)
            {
                selectionBox = new Rectangle(selectionBox.X, selectionBox.Y, ms.X - selectionBox.X, ms.Y - selectionBox.Y);
                isDragging = true;
            }

            else if (ms.LeftButton == ButtonState.Released)
            {
                if (isDragging)
                {
                    searchSelectRectangle(selectionBox);
                }

                selectionBox = new Rectangle(-1, -1, 0, 0);
                isDragging = false;
            }

            prevMs = ms;
        }

        public override void mouseOver(int x, int y)
        {
                foreach (ViewComponent vc in this.components)
                {
                    vc.mouseOver(x, y);
                }
                mapComponent.mouseOver(x, y);
        }

        public override void mousePressed(int x, int y)
        {
                foreach (ViewComponent vc in this.components)
                {
                    vc.mousePressed(x, y);
                }
                mapComponent.mousePressed(x, y);
                if (x < 650)
                {
                    foreach (MapEditorCell c in selectedCells)
                    {
                        c.setSelected(false);
                    }
                    selectedCells.Clear();
                }
        }

        public override void mouseReleased(int x, int y)
        {
                foreach (ViewComponent vc in this.components)
                {
                    vc.mouseReleased(x, y);
                }
                mapComponent.mouseReleased(x, y);
        }
        #endregion

        private List<Tile> getTileList()//List<MapEditorCell> selectedCells)
        {
            List<Tile> selectedTiles = new List<Tile>();
            foreach (MapEditorCell c in selectedCells)
            {
                selectedTiles.Add(c.getTile());
            }

            return selectedTiles;
        }

        public void searchSelectRectangle(Rectangle selection)
        {
            MapEditorCell[][] cells = mapComponent.getCells();
            int cellWidth = cells[0][0].getWidth();
            int cellHeight = cells[0][0].getHeight();
            int offsetX = cells[0][0].getOffsetX();
            int offsetY = cells[0][0].getOffsetY();

            int x0 = selection.Left   - offsetX;
            int y0 = selection.Top - offsetY;
            int x1 = selection.Right - offsetX;
            int y1 = selection.Bottom - offsetY;

            if (x0 > x1)
            {
                int temp = x0;
                x0 = x1;
                x1 = temp;
            }

            if (y0 > y1)
            {
                int temp = y0;
                y0 = y1;
                y1 = temp;
            }

            x0 += cellWidth;
            y0 += cellHeight;

            x0 /= cellWidth;
            y0 /= cellHeight;
            x1 /= cellWidth;
            y1 /= cellHeight;

            for (int i = x0; i < x1; i++)
            {
                for (int j = y0; j < y1; j++)
                {
                    if (i >= 0 && j >= 0 && i < myMap.board.Length && j < myMap.board[0].Length)
                    {
                        selectedCells.Add(cells[i][(myMap.board[0].Length-1)-j]);
                    }
                }
            }
            foreach (MapEditorCell sCell in selectedCells)
            {
                sCell.setSelected(true);
                System.Diagnostics.Debug.WriteLine(sCell.getTile());
            }
        }

        internal void updateMap()
        {
            mapComponent.updateMap();
        }

        internal void setTileType( int type)
        {
            myMap.setTileType(type);//(int)TILE_VARIANTS.HIGH_BANDWIDTH);
        }

        internal void setTiles()
        {
            myMap.applyToGroup(getTileList());
        }

        internal void setStartingArea()
        {
            myMap.applyToGroup(getTileList());
        }

        internal void setTerritories()
        {
            myMap.applyToGroup(getTileList());
        }

        internal void setRaceTerritory()
        {
            myMap.applyToGroup(getTileList());
        }
    }
}
